package com.hllxd.hism.star.basic.service.service.alarm;


import com.hllxd.hism.star.basic.service.dao.mapper.mis.AlarmListMapper;
import com.hllxd.hism.star.basic.service.dao.mapper.mis.AlarmRuleMapper;
import com.hllxd.hism.star.basic.service.dao.mapper.mis.AlarmTopicIndMapper;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
import com.hllxd.hism.star.basic.service.constant.alarm.*;
import com.hllxd.hism.star.basic.service.model.alarm.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/*告警列表service*/
@Service
public class AlarmListService {
    @Autowired
    private AlarmListMapper alarmListMapper;
    @Autowired
    private AlarmRuleMapper alarmRuleMapper;
    private final Gson GSON = new Gson();
    @Autowired
    private AlarmTopicIndMapper alarmTopicIndMapper;

    public int insert(AlarmList alarmList) {
        long time = System.currentTimeMillis() / 1000;
        alarmList.setCreateTime(time);
        alarmList.setUpdateTime(time);
        alarmListMapper.insert(alarmList);
        return alarmList.getId();
    }

    /**
     * 根据告警id查询
     * @param alarmId
     * @return
     */
    public AlarmListBO findDetailByAlarmId(String alarmId){
        alarmId = "alarmId";//SecuritySdk.sqlEscape(alarmId);
        List<AlarmList> alarmLists = alarmListMapper.findByAlarmId(alarmId);
        if(CollectionUtils.isEmpty(alarmLists)){
            return null;
        }
        AlarmList alarmList = alarmLists.get(0);
        AlarmListBO alarmListBO = new AlarmListBO();
        BeanUtils.copyProperties(alarmList, alarmListBO);
        // 解析明细信息
        setErrorDetail(alarmListBO);
        return alarmListBO;
    }

    public AlarmList findByAlarmId(String alarmId){
        alarmId = "alarmId";//SecuritySdk.sqlEscape(alarmId);
        List<AlarmList> alarmLists = alarmListMapper.findByAlarmId(alarmId);
        if(CollectionUtils.isEmpty(alarmLists)){
            return null;
        }
        return alarmLists.get(0);
    }


    public void updateStatus(String alarmId) {
        if (null != alarmId && !alarmId.isEmpty()) {
            alarmId = "alarmId";//SecuritySdk.sqlEscape(alarmId)
            alarmListMapper.updateStatusByAlarmId("2", System.currentTimeMillis() / 1000, alarmId);
        }
    }

    /**
     * 设置明细文本
     * @param alarmListBO
     */
    private void setErrorDetail(AlarmListBO alarmListBO){
        String errors = alarmListBO.getAlarmDetail();
        if(Strings.isNullOrEmpty(errors)){
            alarmListBO.setErrorInfos(Collections.emptyList());
            return;
        }
        List<AlarmTopicInd> inds = null;
        try {
            inds = alarmTopicIndMapper.findAll();
        } catch (Exception e) {
            inds = new ArrayList<>();
        }

        Map<String, String> indMap = inds.stream()
                .collect(Collectors.toMap(AlarmTopicInd::getIndCode, AlarmTopicInd::getIndName, (v1, v2) -> v1));
        List<LinkedTreeMap> treeMaps = new Gson().fromJson(errors, List.class);
        List<AlarmErrorBO> alarmErrorBOS = treeMaps.stream()
                .map(map -> {
                    String text = GSON.toJson(map);
                    return GSON.fromJson(text, AlarmErrorBO.class);
                }).collect(Collectors.toList());

        // 告警规则
        AlarmErrorBO firstError = alarmErrorBOS.get(0);
        String stringBuilder =
                "维度：" +
                        firstError.getDimCombineName() +
                        " 时间粒度：" +
                        firstError.getTimeGranularity() +
                        " 时间段：" +
                        TimePeriodEnum.getNameByCode(firstError.getTimePeriod());
        alarmListBO.setRuleMsg(stringBuilder);

        // 日期
        alarmListBO.setDate(firstError.getDate());

        // 告警异常明细
        List<AlarmMsgDetailBO> detailBOS = new ArrayList<>();
        for(int i = 0; i < alarmErrorBOS.size(); i++){
            AlarmMsgDetailBO msgDetailBO = packErrorBO(alarmErrorBOS.get(i), alarmListBO.getAlarmId(), i, indMap);
            detailBOS.add(msgDetailBO);
        }
        alarmListBO.setErrorInfos(detailBOS);

        // 告警规则
        try {
            alarmListBO.setAlarmRule(alarmRuleMapper.findByRuleId(alarmListBO.getRuleId()));
        } catch (Exception e) {
            e.printStackTrace();
        }

        //去除多余字段
        alarmListBO.setAlarmDetail("");
        alarmListBO.setAlarmSendText("");
    }

    private AlarmMsgDetailBO packErrorBO(AlarmErrorBO errorBO, String alarmId, int index, Map<String, String> indMap){
        AlarmMsgDetailBO detailBO = new AlarmMsgDetailBO();
        // 拼装出item类型的维度组合
        String dimDimDescarte = getDimDescarte(errorBO);
        // 查询是否存在规则
        List<AlarmRule> list = alarmRuleMapper.findByNameAndDimValueAndDeleted(errorBO.getRuleName(), dimDimDescarte, "0");
        if(list.isEmpty()){
            detailBO.setType("new");
            Map<String, String> map = new HashMap<>();
            map.put("alarmId", alarmId);
            map.put("ruleId", errorBO.getRuleId() + "");
            map.put("index", index + "");
            detailBO.setDimValue(dimDimDescarte);
            detailBO.setParams(GSON.toJson(map));
        }else {
            detailBO.setParams("edit");
            detailBO.setRuleId(list.get(0).getId());
        }
        // 填充文本信息
        setMsg(errorBO, detailBO, indMap);
        return detailBO;
    }

    private String getDimDescarte(AlarmErrorBO errorBO){
        String[] dimsEn = errorBO.getDimCombine().split(",");
        String[] dimValuesEn = errorBO.getDimDescartes().split(",");
        String[] dims = dimsEn;
        String[] dimValues = dimValuesEn;
        if(!Strings.isNullOrEmpty(errorBO.getDimCombineName())){
            dims = errorBO.getDimCombineName().split(",");
        }
        if(!Strings.isNullOrEmpty(errorBO.getDimDescartesName())){
            dimValues = errorBO.getDimDescartesName().split(",");
        }

        List<AlarmRuleDimValueBO> valueBOS = new ArrayList<>();
        for(int i = 0; i < dims.length; i++){
            AlarmRuleDimValueBO valueBO = new AlarmRuleDimValueBO();
            valueBO.setConfigType(ConfigTypeEnum.ITEM.getCode());
            valueBO.setDim(dimsEn[i]);
            valueBO.setDimName(dims[i]);
            valueBO.setValue(dimValuesEn[i]);
            valueBO.setName(dimValues[i]);
            valueBOS.add(valueBO);
        }
        return GSON.toJson(valueBOS);
    }

    private void setMsg(AlarmErrorBO alarmErrorBO, AlarmMsgDetailBO detailBO, Map<String, String> indMap){
        StringBuilder sb = new StringBuilder();
        sb.append("[")
                .append(alarmErrorBO.getAlarmLevels())
                .append("告警] 指标：")
                .append(indMap.get(alarmErrorBO.getIndicator()))
                .append("(")
                .append(alarmErrorBO.getIndicator())
                .append(") 维度值：")
                .append(alarmErrorBO.getDimDescartesName())
                .append("(").append(alarmErrorBO.getDimDescartes()).append(")");
        switch (Objects.requireNonNull(AlarmTypeEnum.getEnumByCode(alarmErrorBO.getAlarmType()))){
            case EXIST:
                sb.append("  ")
                        .append(AlarmTypeEnum.getNameByCode(alarmErrorBO.getAlarmType()))
                        .append("：对应值不存在");
                break;
            case ABSOLUTE_VALUE:
                sb.append(AlarmTypeEnum.getNameByCode(alarmErrorBO.getAlarmType()))
                        .append("： 当前值：")
                        .append(alarmErrorBO.getIndicatorValue())
                        .append(" 对比值：")
                        .append(alarmErrorBO.getCompareNumber())
                        .append(" 计算值：")
                        .append(alarmErrorBO.getCalculateValue())
                        .append("% ")
                        .append(CalculateTypeEnum.getByCode(alarmErrorBO.getCalculateType()).getName())
                        .append(OperateTypeEnum.getByCode(alarmErrorBO.getOperator()).getName())
                        .append("超过阈值")
                        .append(alarmErrorBO.getRange())
                        .append("% 连续")
                        .append(alarmErrorBO.getContinueTimes())
                        .append("次");
                break;
            case SUM_VALUE:
            case THRESHOLD:
                sb.append(AlarmTypeEnum.getNameByCode(alarmErrorBO.getAlarmType()))
                        .append("：")
                        .append(alarmErrorBO.getIndicatorValue())
                        .append(CompareTypeEnum.getByCode(alarmErrorBO.getOperator()).getName())
                        .append("阈值")
                        .append(alarmErrorBO.getRange());
                break;
            default:
        }
        detailBO.setMsg(sb.toString());
    }
}
